package cn.passlink.www.Security;

import cn.passlink.www.Enity.sysUser;
import cn.passlink.www.Utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

//这是一个过滤器，所以请求都必须经过
@Component("JwtAuthenticationTokenFilter")
@Slf4j
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        //获取accessToken
        String accessToken = request.getHeader("Authorization");

        //        未登录放行
        if (accessToken == null || accessToken.isEmpty() || !accessToken.startsWith("Bearer ")) {
            //放行
            log.info("未登录放行");
            filterChain.doFilter(request, response);
            return;
        }

        accessToken = accessToken.substring(7); // 去除前面的"Bearer "

        //检查是否过期
        if (JwtUtils.isTokenExpired(accessToken)) {
            //放行
            log.info("accessToken 过期");
            filterChain.doFilter(request, response);
            return;
        }


        //登陆解析解析accessToken内的信息
        sysUser user = JwtUtils.getClaims(accessToken);
        if (user == null) {
            log.error("accessToken 解析失败");
            response.sendError(HttpServletResponse.SC_REQUEST_URI_TOO_LONG, "accessToken非法");
            return;
        }

        //从redis中获取用户信息ID查看是否已经登陆了
        String redisKey = user.getUser_id();
        String loginId = "";
        loginId = (String) redisTemplate.opsForValue().get(redisKey);
        System.out.println("loginId" + loginId);
        log.info("保存登陆信息");
        if (loginId == null || loginId.isEmpty()) {
            System.out.println("loginId为空");
            log.error("loginId为空");
            response.sendError(HttpServletResponse.SC_REQUEST_URI_TOO_LONG, "accessToken非法");
            return;
        }

        //存储登陆用户信息到上下文
        LoginUser loginUser = new LoginUser();
        loginUser.setUser(user);

        // 获取权限信息封装到Authentication中
        log.info("获取权限信息封装到Authentication中");
        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(loginUser, null, null);
        //存入SecurityContextHolder
        log.info("存入SecurityContextHolder");
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        //放行
        filterChain.doFilter(request, response);
    }
}
